/**
 * @module 全局工具函数
 */

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { message } from 'antd'

// message全局配置
message.config({
  maxCount: 2,
  duration: 1.5,
  top: 30
})

// 展示异常信息
export const showError = (msg: string) => {
  message.error(msg)
}

export const showInfo = (msg: string) => {
  message.info(msg)
}

// 成功提示信息
export const showSuccess = (msg: string) => {
  message.success(msg)
}

// 警告提示信息
export const showWarning = (msg: string) => {
  message.warning(msg)
}

const getUserToken = () => {
  return localStorage.getItem('user-token')
}

// 创建一个请求实例，用来处理Token校验相关的请求
// 创建Axios实例
const axiosInstance: AxiosInstance = axios.create({
  baseURL: '/api', // 设置基础URL
  timeout: +(process.env.REQUEST_TIMEOUT || 10000) // 设置请求超时时间
})

// 添加请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    // 在这里添加认证token
    const userToken = getUserToken()
    console.log(userToken, 'token')
    if (userToken) {
      config.headers['Authorization'] = `Bearer ${userToken}`
    } else {
      config.headers['Authorization'] = ''
    }
    return config
  },
  error => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 替换用户Token
const replaceUserTokenByResponse = (response?: AxiosResponse) => {
  const token = response?.headers?.['t-replaced-by']
  console.log(token, 'replace')
  if (token) {
    localStorage.setItem('user-token', token)
  }
}

// 删除用户Token
export const deleteUserToken = () => {
  localStorage.removeItem('user-token')
}

// 添加响应拦截器
axiosInstance.interceptors.response.use(
  response => {
    return Promise.resolve(response)
  },
  error => {
    return Promise.resolve(error?.response)
  }
)

// 处理响应
const handleResponse = (response?: AxiosResponse): void => {
  // 存在token则替换
  replaceUserTokenByResponse(response)
  let messageHandler = showSuccess
  const data = response?.data
  let message = data?.message
  if (response?.status !== 200) {
    messageHandler = showError
  }
  switch (response?.status) {
    case 202:
      messageHandler = showWarning
      break
    case 401:
      showError(message || '您的登录信息已过期，请重新登录')
      setTimeout(jumpToLogin, 1500)
      return
    case 422:
      message = '' // 422错误不展示错误信息
      break
    case 429:
      message = '请求过于频繁，请稍后重试'
      break
    case 500:
      message = message || '服务器异常，请稍后重试'
    default:
      break
  }
  // 展示消息信息
  if (message && messageHandler) {
    console.log(message)
    messageHandler(message)
  }
}

// 封装POST函数
export const apiPost = async <T, Q = unknown>(uri: string, data?: Q, config?: AxiosRequestConfig): Promise<T> => {
  try {
    const response = await axiosInstance.post<T | { data: T }>(uri, data, config)
    handleResponse(response)
    // 处理响应,当返回状态码为200时返回数据
    if ([200, 201].includes(response.status)) {
      if ((response.data as { data: T })?.data) {
        return (response.data as { data: T }).data
      }
      return response.data as T
    } else {
      throw response?.data
    }
  } catch (error) {
    // 处理错误
    console.error('POST Error:', error)
    throw error
  }
}

// 跳转到登录页
export const jumpToLogin = () => {
  deleteUserToken()
  const state = { from: window.location.pathname, search: window.location.search, state: window.history.state }
  window.history.replaceState(state, '', '/login')
  window.location.reload()
}
